package com.wzu.zlb.ems.config;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;

import com.wzu.zlb.ems.shiro.CustomerDBRealm;
import com.wzu.zlb.ems.shiro.PermissionsAuthorizationFilter;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfig {
    //1.创建shiroFilter  //负责拦截所有请求
    @Bean
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Qualifier("securityManage") DefaultWebSecurityManager defaultWebSecurityManager){

        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        //给filter设置安全管理器
        shiroFilterFactoryBean.setSecurityManager(defaultWebSecurityManager);
        Map<String, Filter> filters = new HashMap<>();
        filters.put("permission", new PermissionsAuthorizationFilter());
        shiroFilterFactoryBean.setFilters(filters);
        //配置系统受限资源
        //配置系统公共资源
        Map<String, String> map = new LinkedHashMap<>();

        /*
               anon: 无需认证
               authc: 必须认证了才能访问
               user: 必须拥有 记住我 功能才能访问
               perms: 拥有对某个资源的权限才能访问
               role: 拥有某个角色权限才能访问
         */


        map.put("/home","authc");
        map.put("/product/list","authc");
        map.put("/product/search","authc");
        map.put("/product/detail*","authc");
        map.put("/product/design*","authc");
        map.put("/product/add*","permission[user:admin]");
        map.put("/product/delete*","permission[user:admin]");
        map.put("/product/modify*","permission[user:admin]");

        map.put("/order/list","authc");
        map.put("/order/search","authc");
        map.put("/order/detail*","authc");
        map.put("/order/add*","permission[user:admin]");
        map.put("/order/delete*","permission[user:admin]");
        map.put("/order/modify*","authc");

        map.put("/add/search","permission[user:admin]");

        map.put("/design*","permission[user:admin]");

        map.put("/**","anon");//anon 设置为公共资源


        //默认认证界面路径---当认证不通过时跳转
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        shiroFilterFactoryBean.setUnauthorizedUrl("/login");

        //授权


        //未授权界面
        shiroFilterFactoryBean.setUnauthorizedUrl("/noauth");

        return shiroFilterFactoryBean;
    }

    //2.创建安全管理器
    @Bean(name = "securityManage")
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Qualifier("getRealm") Realm realm){
        DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager();
        //设置安全管理器
        defaultWebSecurityManager.setRealm(realm);

        return defaultWebSecurityManager;
    }

    //3.创建自定义realm
    @Bean
    public Realm getRealm(){
        //CustomerRealm customerRealm = new CustomerRealm();
        CustomerDBRealm realm = new CustomerDBRealm();
        System.out.println("--------------getRealm()方法");

        return realm;
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager){
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }


    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor(){
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    @DependsOn({"lifecycleBeanPostProcessor"})
    public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
        DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        advisorAutoProxyCreator.setProxyTargetClass(true);
        return advisorAutoProxyCreator;
    }



    @Bean(name = "shiroDialect")
    public ShiroDialect shiroDialect(){
        return new ShiroDialect();
    }
}
